package math

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
	"math"
)

// double求余
type DREM struct {
	base.NoOperandsInstruction
}

// float取余
type FREM struct {
	base.NoOperandsInstruction
}

// int取余
type IREM struct {
	base.NoOperandsInstruction
}

// long取余
type LREM struct {
	base.NoOperandsInstruction
}

func (self *DREM)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	v1 := stack.PopDouble()
	v2 := stack.PopDouble()
	// 压栈的时候是被取余的数先压栈，所以被取余的数后弹出
	result := math.Mod(v2,v1)
	stack.PushDouble(result)
}

func (self *FREM)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	v1 := stack.PopFloat()
	v2 := stack.PopFloat()
	// 压栈的时候是被取余的数先压栈，所以被取余的数后弹出
	result := math.Mod(float64(v2),float64(v1))
	stack.PushFloat(float32(result))
}

func (self *IREM)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	v1 := stack.PopInt()
	v2 := stack.PopInt()
	if v2 == 0 {
		panic("java.lang.ArithmeticException")
	}
	result := v2 % v1
	stack.PushInt(result)
}

func (self *LREM)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	v1 := stack.PopLong()
	v2 := stack.PopLong()
	if v2 == 0 {
		panic("java.lang.ArithmeticException")
	}
	result := v2 % v1
	stack.PushLong(result)
}